package com.tangyuan.common.payment;


import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayFundAccountQueryModel;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.domain.Participant;
import com.alipay.api.request.AlipayFundAccountQueryRequest;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayFundAccountQueryResponse;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.tangyuan.Ali.AliPayCashOut;
import com.tangyuan.Ali.AliPayPay;
import com.tangyuan.Ali.AliPayRefund;
import com.tangyuan.common.config.AlipayConfig;
import com.tangyuan.common.result.Result;
import com.tangyuan.common.result.ResultCodeEnum;
import com.tangyuan.common.util.AlipayUtils;
import com.tangyuan.dto.AliPayCashOutDto;
import com.tangyuan.dto.RechargeDto;
import com.tangyuan.model.Orders;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;

@Slf4j
public class AliPayImpl {

    /**
     * 支付宝支付
     *
     * @param request
     * @param response
     * @param orders
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/pay", method = RequestMethod.POST)   // 参数+body 商品描述 type 支付设置
    @ResponseBody
    public String alipay(ServletRequest request, HttpServletResponse response, @RequestBody Orders orders) throws IOException {
        log.info("-------------开始调用支付宝支付接口-------------");
        //这里你可以做一些存表操作..具体根据你们自己的业务来操作... 比如生成预支付订单
        String orderString = "";//这个字符串是用来返回给前端的
        //获得初始化的AlipayClient
        AlipayClient alipayClient = AlipayUtils.getAlipayClient();
        //设置请求参数
        Orders order = null;

        if (order == null) {
            return "当前订单已超时，请重新下单！";
        }
        AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
        alipayRequest.setNotifyUrl(AlipayConfig.NOTIFYURL);
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orders.getOrderNo());

        //判断订单是否在进行中
        bizContent.put("total_amount", orders.getPayBalance());
        bizContent.put("subject", orders.getShopName());
        bizContent.put("product_code", "QUICK_MSECURITY_PAY");
        alipayRequest.setBizContent(bizContent.toString());
        AlipayTradeAppPayResponse responsess = null;
        try {
            log.info("-------------正在准备调用-------------");
            responsess = alipayClient.sdkExecute(alipayRequest);
            log.info(responsess.getBody());
            if (responsess.isSuccess()) {
                log.info("已经调起支付宝支付.....");
                return responsess.getBody();
            } else {
                log.error("调用失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "调用失败";
    }

    public static com.tangyuan.common.result.Result<Object> pay(Orders orders) {
        log.info("-------------开始调用支付宝支付接口-------------");
        //这里你可以做一些存表操作..具体根据你们自己的业务来操作... 比如生成预支付订单
        //获得初始化的AlipayClient
        AlipayClient alipayClient = AlipayUtils.getAlipayClient();
        //设置请求参数
        AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
        alipayRequest.setNotifyUrl(AlipayConfig.NOTIFYURL);
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orders.getOrderNo());
        //判断订单是否在进行中
        bizContent.put("total_amount", orders.getPayBalance());
        bizContent.put("subject", orders.getShopName());
        bizContent.put("product_code", "QUICK_MSECURITY_PAY");
        alipayRequest.setBizContent(bizContent.toString());
        AlipayTradeAppPayResponse responsess = new AlipayTradeAppPayResponse();
        try {
            log.info("-------------正在准备调用-------------");
            responsess = alipayClient.sdkExecute(alipayRequest);
            log.info(responsess.getBody());
            if (responsess.isSuccess()) {
                log.info("已经调起支付宝支付.....");
                return com.tangyuan.common.result.Result.ok(responsess.getBody());
            } else {
                log.error("调用失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return com.tangyuan.common.result.Result.fail("调用失败");
    }

    /**
     * 支付宝退款
     *
     * @param orders
     * @return
     * @throws IOException
     */
    public static Result<Object> refund(Orders orders) throws IOException {

        //这里你可以做一些存表操作..具体根据你们自己的业务来操作... 比如生成预支付订单
        String orderString = "";//这个字符串是用来返回给前端的
        //获得初始化的AlipayClient
        AlipayClient alipayClient = AlipayUtils.getAlipayClient();
        //设置请求参数
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo(orders.getOrderNo());
        model.setOutRequestNo(UUID.randomUUID().toString());
        model.setRefundAmount(orders.getPayBalance().toPlainString());
        alipayRequest.setBizModel(model);
        AlipayTradeRefundResponse responsess = new AlipayTradeRefundResponse();
        AliPayRefund aliPayRefund = new AliPayRefund();
        try {
            responsess = alipayClient.certificateExecute(alipayRequest);
            log.info(responsess.getBody());
            aliPayRefund = JSONObject.parseObject(responsess.getBody(), AliPayRefund.class);
            if (responsess.isSuccess()) {
                log.info("正在调起支付宝退款.....");
                return Result.ok("退款成功");
            } else {
                log.error("调用失败");
                return Result.build(null, ResultCodeEnum.PAY_ERROR.getCode(), aliPayRefund.getAlipayTradeRefundResponse().getSubMsg());
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return Result.build(null, ResultCodeEnum.PAY_ERROR.getCode(), aliPayRefund.getAlipayTradeRefundResponse().getSubMsg());
    }


    /**
     * 支付宝提现
     *
     * @param mzOrder
     * @return
     * @throws IOException
     */
    public static Result<Object> cashOut(Orders mzOrder) throws IOException {
        //这里你可以做一些存表操作..具体根据你们自己的业务来操作... 比如生成预支付订单
        String orderString = "";//这个字符串是用来返回给前端的
        //获得初始化的AlipayClient
        AlipayClient alipayClient = AlipayUtils.getAlipayClient();
        //设置请求参数
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo(mzOrder.getOrderNo());
        model.setOutRequestNo(mzOrder.getShopName());
        model.setRefundAmount(mzOrder.getPayBalance().toString());
        alipayRequest.setBizModel(model);
        AlipayTradeRefundResponse responsess = null;
        AliPayRefund aliPayRefund = new AliPayRefund();
        try {
            responsess = alipayClient.certificateExecute(alipayRequest);
            log.info(responsess.getBody());
            aliPayRefund = JSONObject.parseObject(responsess.getBody(), AliPayRefund.class);
            if (responsess.isSuccess()) {
                log.info("正在调起支付宝提现.....");
                if ("N".equals(aliPayRefund.getAlipayTradeRefundResponse().getFundChange())) {
                    return Result.build(null, ResultCodeEnum.PAY_ERROR.getCode(), aliPayRefund.getAlipayTradeRefundResponse().getOutTradeNo() + "订单资金未发生变化");
                }

                return Result.ok("提现成功");
            } else {
                log.error("调用失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return Result.build(null, ResultCodeEnum.PAY_ERROR.getCode(), aliPayRefund.getAlipayTradeRefundResponse().getSubMsg());
    }

    /**
     * 支付宝支付同步回调
     *
     * @param rawdata
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/callback", method = RequestMethod.POST)
    @ResponseBody
    public Result<Object> callback(@RequestBody Map<String, Object> rawdata) throws IOException {
        AliPayPay aliPayPay = JSONObject.parseObject(String.valueOf(rawdata.get("result")), AliPayPay.class);
        log.info(aliPayPay.getAlipayTradeAppPayResponse().getOutTradeNo());
        log.info("同步回调成功");
        return Result.ok();
    }

    /**
     * 支付宝充值
     *
     * @param rechargeDto
     * @return
     * @throws IOException
     */
    public static String alipays(RechargeDto rechargeDto) throws IOException {
        //这里你可以做一些存表操作..具体根据你们自己的业务来操作... 比如生成预支付订单
        String orderString = "";//这个字符串是用来返回给前端的
        //获得初始化的AlipayClient
        AlipayClient alipayClient = AlipayUtils.getAlipayClient();
        //设置请求参数
        AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
        alipayRequest.setNotifyUrl(AlipayConfig.NOTIFYURL);
//        alipayRequest.setNotifyUrl(AlipayConfig.NOTIFYURL);
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", rechargeDto.getRechargeNo());
        bizContent.put("total_amount", rechargeDto.getRechargeAmount());
        bizContent.put("subject", "心源诚服");
        bizContent.put("product_code", "QUICK_MSECURITY_PAY");
        alipayRequest.setBizContent(bizContent.toString());
        AlipayTradeAppPayResponse responsess = null;
        try {
            responsess = alipayClient.sdkExecute(alipayRequest);
            log.info(responsess.getBody());
            if (responsess.isSuccess()) {
                log.info("正在调起支付宝支付.....");
                return responsess.getBody();
            } else {
                log.error("调用失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "调用失败";
    }

    /**
     * 单笔转账接口
     *
     * @return
     */
    public static Result<Object> transferAccounts(AliPayCashOutDto aliPayCashOutDto) {
        AlipayClient alipayClient = AlipayUtils.getAlipayClient();
        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();

        model.setOutBizNo(aliPayCashOutDto.getOrderNo());
        if (StringUtils.isNotEmpty(aliPayCashOutDto.getRemark())) {
            model.setRemark(aliPayCashOutDto.getRemark());
        }
//        model.setBusinessParams("{\"payer_show_name_use_alias\":\"true\"}");
        model.setBizScene(aliPayCashOutDto.getBizScene());
        Participant payeeInfo = new Participant();
        payeeInfo.setIdentity(aliPayCashOutDto.getIdentity());
        payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
        payeeInfo.setName(aliPayCashOutDto.getName());
        model.setPayeeInfo(payeeInfo);
        model.setTransAmount(aliPayCashOutDto.getTransAmount());
        model.setProductCode("TRANS_ACCOUNT_NO_PWD");
        model.setOrderTitle(aliPayCashOutDto.getOrderTitle());
        request.setBizModel(model);
        AlipayFundTransUniTransferResponse response = new AlipayFundTransUniTransferResponse();
        try {
            response = alipayClient.certificateExecute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        log.info(response.getBody());
        AliPayCashOut aliPayCashOut = JSONObject.parseObject(response.getBody(), AliPayCashOut.class);
        if (response.isSuccess()) {
            log.info("调用成功");
            return Result.ok(aliPayCashOut);
        } else {
            log.error("调用失败");
            return Result.build(aliPayCashOut, ResultCodeEnum.PAY_ERROR);
        }
    }

    /**
     * 查询账户余额(暂不可用)
     *
     * @return
     */
    public static Result<Object> selectQuery() {
        AlipayClient alipayClient = AlipayUtils.getAlipayClient();
        AlipayFundAccountQueryRequest request = new AlipayFundAccountQueryRequest();
        AlipayFundAccountQueryModel model = new AlipayFundAccountQueryModel();
        model.setAlipayUserId("2088541511044546");
        model.setAccountType("ACCTRANS_ACCOUNT");
        request.setBizModel(model);
        AlipayFundAccountQueryResponse response = new AlipayFundAccountQueryResponse();
        try {
            response = alipayClient.certificateExecute(request);
            log.info("账户可用余额：" + response.getAvailableAmount());
            log.info("账户冻结余额：" + response.getFreezeAmount());
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (response.isSuccess()) {
            log.info("调用成功");
            return Result.ok(response);
        } else {
            log.error("调用失败");
        }
        return Result.ok(response);
    }


}
